import 'package:dio/dio.dart';
import 'package:lib_network/lib_network.dart';

enum HttpMethod { post, get, head }

class HttpManager {
  static final HttpManager _instance = HttpManager._internal();
  factory HttpManager() {
    return _instance;
  }

  late Dio _dio;
  Dio get dio => _dio;

  HttpManager._internal() {
    BaseOptions options = BaseOptions(
        baseUrl: HttpConfig().baseURL,
        connectTimeout: HttpConfig().connectTimeout);

    _dio = Dio(options);

    if (HttpConfig().cryptInterceptor != null) {
      //添加拦截器
      _dio.interceptors.add(HttpConfig().cryptInterceptor!);
    }
    _dio.interceptors.add(LogInterceptor());
  }

  _request(String url,
      {HttpMethod method = HttpMethod.post,
      required Map<String, dynamic> params}) async {
    // 1.创建单独配置
    final options = Options(
      method: method.name,
      headers: HttpConfig().headers(),
    );

    // 2.生成请求参数
    //拼接公共参数
    params = (Map<String, dynamic>.from(params))
      ..addAll(await HttpConfig().publicParams());

    // 3.发送网络请求
    try {
      Response response = await _dio.request(url,
          data: params, queryParameters: params, options: options);

      var respData = response.data;

      return respData;
    } on DioException catch (e) {
      return Future.error(e);
    }
  }

  //返回单个对象的网络请求
  Future<BaseResp?> post(String url, Map<String, dynamic> params) async {
    // 发送网络请求
    try {
      var responseJson =
          await _request(url, params: params, method: HttpMethod.post);
      var model = BaseResp(responseJson);
      if (model.code == HttpConfig().successCode) {
        return model;
      } else {
        if (HttpConfig().failCodeList.contains(model.code)) {
          //如果是统一业务逻辑错误，那就走错误的回调，返回null。
          HttpConfig().failCallBack(model.code, model.msg);
          throw Exception("Network anomaly");
        } else {
          //独立的错误逻辑，就交给每个独立的请求位置
          return model;
        }
      }
    } catch (error) {
      //崩溃部分的错误
      throw Exception(error);
      // return Future.error(error);
    }
  }

  //返回单个对象的网络请求
  Future<BaseResp?> get(String url, Map<String, dynamic> params) async {
    // 发送网络请求
    try {
      var responseJson =
          await _request(url, params: params, method: HttpMethod.get);
      var model = BaseResp(responseJson);
      if (model.code == HttpConfig().successCode) {
        return model;
      } else {
        if (HttpConfig().failCodeList.contains(model.code)) {
          //如果是统一业务逻辑错误，那就走错误的回调，返回null。
          HttpConfig().failCallBack(model.code, model.msg);
          throw Exception("Network anomaly");
        } else {
          //独立的错误逻辑，就交给每个独立的请求位置
          return model;
        }
      }
    } catch (error) {
      //崩溃部分的错误
      // return Future.error(e);
      throw Exception(error);
    }
  }

  //返回单个对象的网络请求
  Future<void> head(String url, Map<String, dynamic> params) async {
    // 发送网络请求
    try {
      await _dio.head(url);
    } on DioException catch (e) {
      print(e);
    }
  }
}
